﻿using Newtonsoft.Json;
using Prism.Events;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.Sockets;
using System.Text;
using System.Threading.Tasks;
using System.Xml.Linq;
using ZoneLineNew.Common;
using ZoneLineNew.Core;
using ZoneLineNew.Enums;
using ZoneLineNew.Models.Entity.Template;
using ZoneLineNew.Models.PrintResult;
using ZoneLineNew.Models.StationConfig;
using ZoneLineNew.Models.StationResult.HOPStation;
using ZoneLineNew.Services.DB;
using ZoneLineNew.Services.Print;

namespace ZoneLineNew.Services.Station.HOPStation {
    /// <summary>
    /// 上支撑螺母拧紧工位
    /// </summary>
    /// <remarks>
    /// <para>StationCode：OP640</para>
    /// <para>IP：192.168.10.25</para>
    /// </remarks>
    public class HOP040StationService : WorkStationBaseService<HOP040StationResult, HOP040StationConfig> {
        
        public HOP040StationService(
            IDbOperate<IFreeSqlMainContext> mainDbOperate, 
            IEventAggregator eventAggregator,
            PrinterLabelService printerService
            ) 
            : base(mainDbOperate, eventAggregator, printerService) {

            //LinkScanBarCodeGun();
            base.InitReSetAddr();
        }

        #region 查重功能

        private bool _repeatCheckSignal;
        /// <summary>
        /// 查重请求 1：触发 0：复位
        /// </summary>
        public bool RepeatCheckSignal
        {
            get { return _repeatCheckSignal; }
            protected set
            {
                SetProperty(ref _repeatCheckSignal, value);
            }
        }

        private string _scanQrCode1;
        /// <summary>
        /// 扫码1
        /// </summary>
        public string ScanQrCode1 {
            get { return _scanQrCode1; }
            set { _scanQrCode1 = value; base.RaisePropertyChanged(); }
        }

        private string _scanQrCode2;
        /// <summary>
        /// 扫码2
        /// </summary>
        public string ScanQrCode2 {
            get { return _scanQrCode2; }
            set { _scanQrCode2 = value; base.RaisePropertyChanged(); }
        }

        #endregion



        public override void DealData(byte[] content) {
            StationRecordData.AbsScanCode = GetPlcString(content, 280);
            //StationRecordData.NutScanCode = GetPlcString(content, 322);
            StationRecordData.PartType = GetPlcString(content, 1002);
            StationRecordData.Result = _client.ByteTransform.TransInt16(content, 1000).ToString().Equals("1") ? "OK" : "NG";
            StationRecordData.TigtenTorque = _client.ByteTransform.TransSingle(content, 1016);
            StationRecordData.TigtenAngle = _client.ByteTransform.TransSingle(content, 1020);
            StationRecordData.CycleTime = _client.ByteTransform.TransSingle(content, 1024);
            StationRecordData.ThreadLength = _client.ByteTransform.TransSingle(content, 510);

            //TriggerPrint = _client.ByteTransform.TransInt16(content, 500);
            //HandSignalPrint = _client.ByteTransform.TransInt16(content, 506);
            //Index = _client.ByteTransform.TransInt16(content, 504);

            //批次追溯
            StationRecordData.NutScanCode = _client.ReadString("DB1100.DBX0").Content;
            StationRecordData.UpwardSupportScanCode = _client.ReadString("DB1100.DBX50").Content;
            StationRecordData.BufferBlockScanCode = _client.ReadString("DB1100.DBX100").Content;
            StationRecordData.DustCoverScanCode = _client.ReadString("DB1100.DBX150").Content;
            StationRecordData.DustCapScanCode = _client.ReadString("DB1100.DBX200").Content;
            StationRecordData.LabelCapScanCode = _client.ReadString("DB1100.DBX250").Content;

            #region 查重功能 数据接收  第二个上传条码指令
            RepeatCheckSignal = _client.ReadInt16("DB99.100").Content == (Int16)1;
            ScanQrCode1 = _client.ReadString("DB99.0").Content;
            ScanQrCode2 = _client.ReadString("DB99.50").Content;
            #endregion
        }

        public override void DealWithCommonData(byte[] content) {
            Heart = _client.ByteTransform.TransInt16(content, 8) == (short)1;
            StartUploadCode = _client.ByteTransform.TransInt16(content, 6) == (Int16)1;
            StartUploadData = _client.ByteTransform.TransInt16(content, 10) == (Int16)1;

            HeartToPlc = _client.ReadInt16("DB1001.DBW0").Content == (Int16)1;
            EndUpLoadCode = _client.ReadInt16("DB1001.8").Content == (Int16)1;
            EndUpLoadData = _client.ReadInt16("DB1001.2").Content == (Int16)1;
            AllowWork = _client.ReadInt16("DB1001.8").Content;
        }

        public override void DealWithSignal(string signalName)
        {

            if (signalName == nameof(StartUploadCode))
            {
                //todo 上传了条码 这时候验证是否要工作
                if (StartUploadCode)
                {
                    LogWithUi($"在{CurrentStationName}收到上传条码信息命令", StationRecordData.AbsScanCode);

                    #region 验证缸体码是否合格
                    LogWithUi($"在{CurrentStationName}工位检查缸体码是否合格", StationRecordData.AbsScanCode);
                    var codeRes = base.MainCodeVerify(StationRecordData.AbsScanCode);
                    LogWithUi($"在{CurrentStationName}工位检查缸体码是否合格{StationRecordData.AbsScanCode}的结论是{codeRes}", StationRecordData.AbsScanCode);
                    if (!codeRes) {
                        LogWithUi($"在{CurrentStationName}工位检查缸体码不合格", StationRecordData.AbsScanCode);
                        var writeRlt0 = WriteWorkActionToPlc(StationConfig.AllowWorkAddr, WorkActionEnum.CodeErr, StationRecordData.AbsScanCode);
                        LogWithUi($"在{CurrentStationName}工位向下位机下发消息，下发{writeRlt0}", StationRecordData.AbsScanCode);
                        return;
                    }
                    #endregion

                    LogWithUi($"在{CurrentStationName}工位结论验证,条码信息是{StationRecordData.AbsScanCode}", StationRecordData.AbsScanCode);
                    var validataRlt = Validata(CurrentStationName, StationRecordData.AbsScanCode);
                    LogWithUi($"在{CurrentStationName}工位的验证结果是{validataRlt}", StationRecordData.AbsScanCode);
                    var writeRlt = WriteWorkActionToPlc(StationConfig.AllowWorkAddr, validataRlt, StationRecordData.AbsScanCode);
                    LogWithUi($"在{CurrentStationName}工位向下位机下发消息，下发{writeRlt}", StationRecordData.AbsScanCode);
                }
                else
                {
                    LogWithUi($"在{CurrentStationName}收到上传条码命令变为false", StationRecordData.AbsScanCode);
                    WriteData(StationConfig.EndUploadCodeAddr, 0, StationRecordData.AbsScanCode);
                    WriteData(StationConfig.AllowWorkAddr, 0, StationRecordData.AbsScanCode);
                    LogWithUi($"在{CurrentStationName}复位工作控制指令和复位上传条码完成指令", StationRecordData.AbsScanCode);

                    WriteData(StationConfig.PrintRltAddr, 0, StationRecordData.AbsScanCode);//清空PLC打标标记
                    LogWithUi($"在{CurrentStationName}打标记录,clear", StationRecordData.AbsScanCode);
                }
                return;
            }

            if (signalName == nameof(StartUploadData))
            {
                //todo 上传数据 这时候将数据记录到数据库中
                if (StartUploadData)
                {
                    LogWithUi($"在{CurrentStationName}1收到记录数据命令", StationRecordData.AbsScanCode);
                    var rlt = RecordData();
                    WriteData(StationConfig.EndUploadDataAddr, (short)rlt, StationRecordData.AbsScanCode);
                    LogWithUi($"在{CurrentStationName}1数据记录,rlt={rlt}", StationRecordData.AbsScanCode);
                    if (rlt == 1) //liyuxing for update 2025-07-23 将此工位的测高、打标功能独立出来
                    {
                        LogWithUi($"在{CurrentStationName}数据记录完成,打印标签开始", StationRecordData.AbsScanCode);
                        PrintLabel(StationRecordData.AbsScanCode);
                        LogWithUi($"在{CurrentStationName}数据记录完成,打印标签完成", StationRecordData.AbsScanCode);
                    }
                }
                else
                {
                    LogWithUi($"在{CurrentStationName}收到上传数据信息变为false", StationRecordData.AbsScanCode);
                    WriteData(StationConfig.EndUploadDataAddr, 0, StationRecordData.AbsScanCode);
                    LogWithUi($"在{CurrentStationName}数据记录,clear", StationRecordData.AbsScanCode);
                }
            }

            #region 查重验证
            if (signalName == nameof(RepeatCheckSignal))
            {
                if (RepeatCheckSignal)
                {
                    LogWithUi($"在{CurrentStationName}收到查重条码信息命令，ScanQrCode1：{ScanQrCode1}|ScanQrCode2：{ScanQrCode2}");
                    if (AppSession.Config.IsEnabledScanCodeCheckRepeatVerify)
                    {
                        var repeatlist = _mainDbOperate.GetModelList<AbsPrintResult>(o => o.AbsCode == ScanQrCode1 && o.Code == ScanQrCode2);
                        if (repeatlist == null || repeatlist.Count == 0)
                        {
                            repeatlist = _mainDbOperate.GetModelList<AbsPrintResult>(o => o.AbsCode == ScanQrCode2 && o.Code == ScanQrCode1);
                        }
                        var rlt = (repeatlist.Count == 1);
                        WriteData("DB99.102", (rlt == true ? (short)1 : (short)2), $"ScanQrCode1：{ScanQrCode1}|ScanQrCode2：{ScanQrCode2}");
                        LogWithUi($"在{CurrentStationName}查重条码信息完成，结果：{rlt}，ScanQrCode1：{ScanQrCode1}|ScanQrCode2：{ScanQrCode2}");
                    }
                    else
                    {
                        LogWithUi($"在{CurrentStationName}收到查重条码信息命令，结果：【未启用】，ScanQrCode1：{ScanQrCode1}|ScanQrCode2：{ScanQrCode2}");
                    }
                }
                else
                {
                    LogWithUi($"在{CurrentStationName}收到查重条码信息命令变为false，ScanQrCode1：{ScanQrCode1}|ScanQrCode2：{ScanQrCode2}");
                    WriteData("DB99.102", 0, $"ScanQrCode1：{ScanQrCode1}|ScanQrCode2：{ScanQrCode2}");
                }
            }
            #endregion
        }

        public override int RecordData() {
            var result = new HOP040StationResult() {
                AbsScanCode = StationRecordData.AbsScanCode,
                StationCode = StationConfig.StationCode,
                PartType = StationRecordData.PartType,
                Result = StationRecordData.Result,
                TigtenTorque = StationRecordData.TigtenTorque,
                TigtenAngle = StationRecordData.TigtenAngle,
                CycleTime = StationRecordData.CycleTime,
                ThreadLength = StationRecordData.ThreadLength,
                CreateTime = DateTime.Now,
                ProductID = Cache.CurWorkProduct.Id,
                //以下是批次追溯字段
                NutScanCode = StationRecordData.NutScanCode,
                UpwardSupportScanCode = StationRecordData.UpwardSupportScanCode,
                BufferBlockScanCode = StationRecordData.BufferBlockScanCode,
                DustCoverScanCode = StationRecordData.DustCoverScanCode,
                DustCapScanCode = StationRecordData.DustCapScanCode,
                LabelCapScanCode = StationRecordData.LabelCapScanCode,
            };
            var writeRlt = false;
            if (_mainDbOperate.CheckExist<HOP040StationResult>(p => p.AbsScanCode == result.AbsScanCode && !result.IsReworked)) {
                var beforeRlt = _mainDbOperate.GetModel<HOP040StationResult>(p => p.AbsScanCode == result.AbsScanCode && !result.IsReworked);
                result.Id = beforeRlt.Id;
                writeRlt = _mainDbOperate.UpdateModelSuper<HOP040StationResult>(p => p.AbsScanCode == result.AbsScanCode && !result.IsReworked, result);
                LogWithUi($"在{CurrentStationName}工位数据更新,rlt={writeRlt}", StationRecordData.AbsScanCode);
            } else {
                writeRlt = _mainDbOperate.AddModel(result);
                LogWithUi($"在{CurrentStationName}工位数据新增,rlt={writeRlt}", StationRecordData.AbsScanCode);
            }
            return writeRlt ? 1 : 2;
        }


        private void PrintLabel(string barCode) {

            var temp = _mainDbOperate.GetModel<TemplateEntity>(o => o.ProductID == Cache.CurWorkProduct.Id && o.TemplateType == eTemplateType.LabelCode);
            if (temp != null) {
                try {

                    var printParams = base.GeneratePrintParams(temp, ePrintStartionCode.H_OP640, barCode);

                    //打印成功，将数据打印的数据记录到关联表中
                    var printRecord = new AbsPrintResult() {
                        Brand = Cache.CurWorkProduct.CustomerName,
                        Model = Cache.CurWorkProduct.Model,
                        AbsCode = barCode,
                        Code = printParams.qrCode,
                        LeftRight = (int)Cache.CurWorkProduct.WorkDirection,
                        PrintTime = DateTime.Now,
                        ProductID = Cache.CurWorkProduct.Id,
                        PrintParams = JsonConvert.SerializeObject(printParams.printParams),
                    };
                    var isAddSuccess = _mainDbOperate.AddModel(printRecord);
                    var isUpdateSuccess = _mainDbOperate.UpdateModel<HOP040StationResult>(p => p.AbsScanCode == printRecord.AbsCode && !p.IsReworked, p => new HOP040StationResult { Code = printParams.qrCode });
                    
                    if (isAddSuccess && isUpdateSuccess) {

                        LogWithUi($"在{CurrentStationName}开始打印工件标签，模板是【${temp.TemplatePath}】", barCode);
                        LogWithUi($"在{CurrentStationName}打印第【{printParams.curIndex}】个工件、标签码【{printParams.qrCode}】下发打印任务完成", barCode);

                        _printerService.PrintLabel(temp.TemplatePath, StationConfig.PrinterName, printParams.qrCode, printParams.printParams, absScanCode: barCode);

                        //同步到老系统表
                        ProductIndexHelper.SynchronizeToOldSystemIndex(Cache.CurWorkProduct, ePrintStartionCode.H_OP640);

                        _ = Task.Run(() => {
                            _mainDbOperate.UpdateModel<HOP010StationResult>(p => p.AbsScanCode == printRecord.AbsCode && !p.IsReworked, p => new HOP010StationResult { Code = printParams.qrCode });
                        });

                        LogWithUi($"在{CurrentStationName}打印成功", barCode);
                        WriteData(StationConfig.PrintRltAddr, 1, barCode);

                    } else {
                        LogWithUi($"在{CurrentStationName}打印失败，失败原因：记录打印结果到数据库失败", barCode);
                        WriteData(StationConfig.PrintRltAddr, 2, barCode);
                    }

                } catch (Exception ex) {

                    LogWithUi($"在{CurrentStationName}打印失败，失败原因{ex.Message}", barCode);
                    WriteData(StationConfig.PrintRltAddr, 2, barCode);

                }
               GetCurrentLableIndex(ePrintStartionCode.H_OP640);
            }
        }

        private void LinkScanBarCodeGun() {

            _ = Task.Factory.StartNew(() => {

                try {
                    // 配置目标IP和端口号
                    string ipAddress = "192.168.10.118";  // 扫码枪的IP地址
                    int port = 2002;  // 扫码枪的端口号

                    // 创建TcpClient并连接到目标IP和端口
                    TcpClient tcpClient = new TcpClient();
                    tcpClient.Connect(ipAddress, port);

                    // 获取网络流
                    NetworkStream stream = tcpClient.GetStream();

                    // 创建数据缓冲区
                    byte[] buffer = new byte[1024];

                    // 读取数据（例如，扫描的条形码）
                    int bytesRead;
                    while ((bytesRead = stream.Read(buffer, 0, buffer.Length)) != 0) {
                        string data = Encoding.ASCII.GetString(buffer, 0, bytesRead);
                        var tempCode = data.Replace(Environment.NewLine, "");
                        LogWithUi($"接收到查重扫码抢数据: {tempCode}");
                        if (!string.IsNullOrEmpty(data)) {
                            var res = _mainDbOperate.GetModelList<HOP040StationResult>(p => p.Code == tempCode);
                            WriteData("DB1001.28", res.Count == 1 ? (short)0 : (short)1, StationRecordData.AbsScanCode);
                        }
                    }
                } catch (Exception ex) {
                    LogManager.Error(ex);
                    //throw;
                }
            });
        }
    }
}
